﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MIAP.DataAccess.Interfaces;
using MIAP.DataAccess.SqlServer.Model;
using MIAP.Entidades;

namespace MIAP.DataAccess.Implementaciones.SQL
{
    public class ConfiguracionDao : IConfiguracionDao
    {
        #region Constantes

        private const string PERFIL_ADMINISTRADOR = "IdPerfilAdministrador";
        private const string REGISTROS_GRID = "RegisterPerPage";
        private const string RUTA_ARCHIVOS = "RutaArchivos";
        private const string RUTA_PAQUETES = "RutaPaquetes";
        private const string ID_VARIABLE_USER = "IdVariablesUser";
        private const string VARIABLE_FILENAME = "VariableFileName";
        private const string DOMINIO = "Dominio";
        private const string USER = "UsuarioRed";
        private const string PASSWORD = "PasswordUsrRed";
        private const string DOMINIOCORREO = "DominioCorreo";
        private const string USERCORREO = "UsuarioCorreo";
        private const string PASSWORDCORREO = "PasswordCorreo";
        private const string FROMCORREO = "CorreoFrom";
        private const string CORREOSERRORES = "CorreosErrores";
        private const string SERVERPKG = "ServerPkg";
        private const string USERWINSERVERPKG = "UsrWindowsPkg";
        private const string PWDWINSERVERPKG = "PwdWindowPkg";
        private const string RUTADTEXCEC = "RutaDtExec";

        private const string PREFIJOVAR = "Variables_";


        #endregion

        #region Metodos

        /// <summary>
        /// Obtiene la configuración para el perfil del administrador.
        /// </summary>
        /// <returns>Información del perfil del administrador.</returns>
        public CatalogoInfo GetConfiguracionPerfilAdministrador()
        {
            return this.GetValorConfiguracion(PERFIL_ADMINISTRADOR);
        }

        /// <summary>
        /// Obtiene la configuración del numero de registros que se mostraran por pagina en el grid
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetNumeroPaginasGrid()
        {
            return this.GetValorConfiguracion(REGISTROS_GRID);
        }

        /// <summary>
        /// Obtiene la ruta en donde se encotraran los archivos
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetRutaArchivos()
        {
            return this.GetValorConfiguracion(RUTA_ARCHIVOS);
        }

        /// <summary>
        /// Obtiene la ruta en donde se encotraran los paquetes.
        /// </summary>
        /// <returns>Un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetRutaPaquetes()
        {
            return this.GetValorConfiguracion(RUTA_PAQUETES);
        }

        /// <summary>
        /// Obtiene la configuración para el perfil del administrador.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetIdentificadorVariabesUsuario()
        {
            return this.GetValorConfiguracion(ID_VARIABLE_USER);
        }

        /// <summary>
        /// Obtiene el nombre de la variable del filename.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetNombreVarFileName()
        {
            return this.GetValorConfiguracion(VARIABLE_FILENAME);
        }

        /// <summary>
        /// Obtiene el nombre del dominio a utilizar para la funcion de impersonate.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetNombreDominioImpersonate()
        {
            return this.GetValorConfiguracion(DOMINIO);
        }

        /// <summary>
        /// Obtiene el nombre del usuario a utilizar para la funcion de impersonate.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetNombreUserImpersonate()
        {
            return this.GetValorConfiguracion(USER);
        }

        /// <summary>
        /// Obtiene el nombre del password del usuario a utilizar para la funcion de impersonate.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetNombrePasswordImpersonate()
        {
            return this.GetValorConfiguracion(PASSWORD);
        }

        /// <summary>
        /// Obtiene el valor de algun registro en el archivo de configuracion
        /// </summary>
        /// <param name="claveConf">clave de la cual queremos obtener el valor</param>
        /// <returns></returns>
        private CatalogoInfo GetValorConfiguracion(string claveConf)
        {
            CatalogoInfo result;
            using (var context = new MIAPDBEntities())
            {
                var query = (from configuracion in context.MIAP_CONFIGURACION
                             where configuracion.CLAVE == claveConf
                             select new CatalogoInfo
                             {
                                 Descripcion = configuracion.VALOR
                             }).Single();
                result = query;
            }
            return result;
        }


        /// <summary>
        /// Obtiene el nombre del password del usuario a utilizar para el envio de correo.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetNombrePasswordcorreo()
        {
            return this.GetValorConfiguracion(PASSWORDCORREO);
        }

        /// <summary>
        /// Obtiene el nombre del usuario a utilizar parael envio de correo.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetNombreUserCorreo()
        {
            return this.GetValorConfiguracion(USERCORREO);
        }

        /// <summary>
        /// Obtiene el nombre del dominio a utilizar para el envio de correo.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetNombreDominioCorreo()
        {
            return this.GetValorConfiguracion(DOMINIOCORREO);
        }

        /// <summary>
        /// Obtiene el correo (from) para utilizar en el envio de correo.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetFromEnvioCorreo()
        {
            return this.GetValorConfiguracion(FROMCORREO);
        }

        /// <summary>
        /// Obtiene los correos a los cuales se le enviara notificacion si es que ocurre algún error en la aplicación.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetFromCorreosErrores()
        {
            return this.GetValorConfiguracion(CORREOSERRORES);
        }

        /// <summary>
        /// Obtiene el nombre del server a utilizar para la ejecucion de paquetes desde base.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetNombreServerPkg()
        {
            return this.GetValorConfiguracion(SERVERPKG);
        }

        /// <summary>
        /// Obtiene el password del usuario de windows a utilizar para la ejecucion de paquetes desde base.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetNombreWindowsPasswordServerPkg()
        {
            return this.GetValorConfiguracion(PWDWINSERVERPKG);
        }

        /// <summary>
        /// Obtiene el nombre del usuario de windows a utilizar para la ejecucion de paquetes desde base.
        /// </summary>
        /// <returns>un objeto catalogo info con la información contenida en la variable descripcion</returns>
        public CatalogoInfo GetNombreWindowsUserServerPkg()
        {
            return this.GetValorConfiguracion(USERWINSERVERPKG);
        }

        /// <summary>
        /// Obtiene la cadena de conexion de la base de datos
        /// </summary>
        /// <returns></returns>
        public string GetConnectionString()
        {
            string conection;
            using (var context = new MIAPDBEntities())
            {
                conection = context.Database.Connection.ConnectionString;
            }
            return conection;
        }

        /// <summary>
        /// Obtiene la lista de variables que se necesitan para la ejecucion del paquete
        /// </summary>
        /// <param name="nombrePaquete">nombre del paquete a buscar</param>
        /// <returns>lista con las variables que se necesitaran llenar para la ejecucion del paquete</returns>
        public List<string> GetVariablesPaquete(string proyecto, string NomrbeArch)
        {
            var listaVariables = new List<string>();
           
            using (var context = new MIAPDBEntities())
            {
                var nombrevar = PREFIJOVAR + proyecto.Replace(" ", string.Empty) +
                                (!string.IsNullOrEmpty(NomrbeArch)
                                     ? "_" + NomrbeArch.Replace(" ", string.Empty)
                                     : string.Empty);
                var query =
                    (from config in context.MIAP_CONFIGURACION where config.CLAVE.Contains(PREFIJOVAR) && config.CLAVE==nombrevar select config)
                        .SingleOrDefault();
                if (query != null)
                {
                    listaVariables = query.VALOR.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries).ToList();

                }
            }
            return listaVariables;
        }

        /// <summary>
        /// valida el nombre del paquete si es que tiene ruta
        /// </summary>
        /// <param name="nombrePaquete"></param>
        /// <returns></returns>
        private static string GetNombrePaquete(string nombrePaquete)
        {
            string nombre;
            if (nombrePaquete.Contains(@"\"))
            {
                var split = nombrePaquete.Split(new[] { @"\" }, StringSplitOptions.None);
                nombre = split[split.Count() - 1];
            }
            else if (nombrePaquete.Contains(@"/"))
            {
                var split = nombrePaquete.Split(new[] { @"/" }, StringSplitOptions.None);
                nombre = split[split.Count() - 1];
            }
            else
            {
                nombre = nombrePaquete;
            }
            return nombre;
        }

        /// <summary>
        /// Obtiene la ruta de el ejecutable dtexec en el servidor (ya sea 32 0 64 bits)
        /// </summary>
        /// <returns>Un objeto catalogo info con la información contenida en la variable descripción</returns>
        public CatalogoInfo GetRutaDtExcec()
        {
            return this.GetValorConfiguracion(RUTADTEXCEC);
        }

        /// <summary>
        ///Inserta las variables de configuración que tendrá un paquete
        /// </summary>
        /// <returns></returns>
        public void SetVariablesPaquete(string nombreProy, string nombreArchivo, string user, List<string> variables)
        {
            var variableBD = new StringBuilder();
            foreach (var variable in variables.Where(variable => !String.IsNullOrEmpty(variable)))
            {
                variableBD.Append(variable.Trim());
                variableBD.Append(";");
            }
            using (var context = new MIAPDBEntities())
            {
                var nombreArch = !string.IsNullOrEmpty(nombreArchivo) ? "_" + nombreArchivo.Replace(" ", string.Empty) : string.Empty;
                var config = new MIAP_CONFIGURACION();
                config.CLAVE = PREFIJOVAR + nombreProy.Replace(" ", string.Empty) + nombreArch;
                config.DESCRIPCION = "Variables que se utilizarán";
                config.VALOR = variableBD.ToString();
                config.FECHA_CREACION = DateTime.Now;
                config.FECHA_ACTUALIZACION = DateTime.Now;
                config.USUARIO_ACTUALIZACION = user;
                config.USUARIO_CREACION = user;
                context.MIAP_CONFIGURACION.Add(config);
                context.SaveChanges();
            }
        }

        /// <summary>
        ///edita las variables de configuración que tendrá un paquete
        /// </summary>
        /// <returns></returns>
        public void EditVariablesPaquete(string nombreAntProy, string nombreProy, string nombreAnteriorArchivo, string nombreArchivo, string user, IEnumerable<string> variables)
        {
            var variableBD = new StringBuilder();
            foreach (string variable in variables.Where(variable => !String.IsNullOrEmpty(variable)))
            {
                variableBD.Append(variable.Trim());
                variableBD.Append(";");
            }

            using (var context = new MIAPDBEntities())
            {
                string nombreArch;
                if (!string.IsNullOrEmpty(nombreArchivo))
                {
                    nombreArch = !string.IsNullOrEmpty(nombreArchivo) ? "_" + nombreAnteriorArchivo.Replace(" ", string.Empty) : string.Empty;
                    nombreArch = PREFIJOVAR + nombreProy.Replace(" ", string.Empty) + nombreArch;
                }
                else
                {                    
                    nombreArch = PREFIJOVAR + nombreAntProy.Replace(" ", string.Empty);
                }
                
                var config = (from configuration in context.MIAP_CONFIGURACION
                              where configuration.CLAVE == nombreArch
                              select configuration).Single();

                if ( ((!String.IsNullOrEmpty(nombreAnteriorArchivo) &&!String.IsNullOrEmpty(nombreAnteriorArchivo) ) &&
                    nombreAnteriorArchivo.ToLower() == nombreArchivo.ToLower()) ||
                    ((!String.IsNullOrEmpty(nombreAntProy) && !String.IsNullOrEmpty(nombreProy)) &&
                    nombreAntProy.ToLower() == nombreProy.ToLower()))
                {
                    config.VALOR = variableBD.ToString();
                    config.FECHA_ACTUALIZACION = DateTime.Now;
                    config.USUARIO_ACTUALIZACION = user;
                }
                else
                {
                    nombreArch = !string.IsNullOrEmpty(nombreArchivo) ? "_" + nombreArchivo.Replace(" ", string.Empty) : string.Empty;
                    nombreArch = PREFIJOVAR + nombreProy.Replace(" ", string.Empty) + nombreArch;
                    var config2 = new MIAP_CONFIGURACION();
                    config2.CLAVE = nombreArch;
                    config2.DESCRIPCION = "Variables que se utilizarán";
                    config2.VALOR = variableBD.ToString();
                    config2.FECHA_CREACION = config.FECHA_CREACION;
                    config2.FECHA_ACTUALIZACION = DateTime.Now;
                    config2.USUARIO_ACTUALIZACION = user;
                    config2.USUARIO_CREACION = config.USUARIO_CREACION;
                    context.MIAP_CONFIGURACION.Add(config2);
                    context.MIAP_CONFIGURACION.Remove(config);
                }

                context.SaveChanges();
            }
        }

        #endregion
    }
}
